﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.Windows.Forms;
using Microsoft.VisualStudio.SharePoint;
using Microsoft.VisualStudio.SharePoint.Explorer;
using Microsoft.VisualStudio.SharePoint.Explorer.Extensions;
using Microsoft.SharePoint.Client;
using System.Resources;
using System.Reflection;
using System.IO;

namespace SPMetalExtended.BasicTemplate
{

    [Export(typeof(IExplorerNodeTypeExtension))]
    [ExplorerNodeType(ExplorerNodeTypes.SiteNode)]
    internal class SiteNodeExtensionWithContextMenu : IExplorerNodeTypeExtension
    {
        public void Initialize(IExplorerNodeType nodeType)
        {
            nodeType.NodeMenuItemsRequested += nodeType_NodeMenuItemsRequested;
        }

        void nodeType_NodeMenuItemsRequested(object sender, ExplorerNodeMenuItemsRequestedEventArgs e)
        {
            IMenuItem menuItem = e.MenuItems.Add("Display Message");
            menuItem.Click += menuItem_Click;
        }

        void menuItem_Click(object sender, MenuItemEventArgs e)
        {
            IExplorerNode node = (IExplorerNode)e.Owner;
        }
    }

    [Export(typeof(IExplorerNodeTypeExtension))]
    [ExplorerNodeType(ExtensionNodeTypes.FieldNode)]
    internal class FieldNodeExtensionWithContextMenu : IExplorerNodeTypeExtension
    {
        public void Initialize(IExplorerNodeType nodeType)
        {
            nodeType.NodeMenuItemsRequested += nodeType_NodeFieldItemsRequested;
        }

        void nodeType_NodeFieldItemsRequested(object sender, ExplorerNodeMenuItemsRequestedEventArgs e)
        {
            IMenuItem menuItem = e.MenuItems.Add("Extend SPMetal Code");
            menuItem.Click += viewItem_Click;
        }

        void viewItem_Click(object sender, MenuItemEventArgs e)
        {
            string code = "";
            StringBuilder msg = new StringBuilder();
            IExplorerNode node = (IExplorerNode)e.Owner;
            IFieldNodeInfo fn = node.Annotations[typeof(IFieldNodeInfo)] as IFieldNodeInfo;
            Guid listGuid = fn.ListId;
            Guid fieldGuid = fn.Id;

            string siteurl = node.Context.SiteUrl.AbsoluteUri;
            ClientContext ct = new ClientContext(siteurl);
            List list = ct.Web.Lists.GetById(listGuid);
            ct.Load(list);
            Field field = list.Fields.GetById(fieldGuid);
            ct.Load(field);
            ct.ExecuteQuery();
            string listName = list.Title.Replace(" ","");
            string fieldName = node.Text.Replace(" ","");
            string strNamespace = "$AssemblyFullName$";
            if (field.TypeAsString == "Image")
            {
                code = BuildCode.PublishingImage(node.Text, listName, strNamespace);
                msg.AppendFormat("{0}SPMetal Extended - The code is on your Clipboard. {0}Paste the code into a class in your project and adjust the namespace.{0}", Environment.NewLine);
            }
            else if (field.TypeAsString == "HTML")
            {
                Assembly assembly = this.GetType().Assembly;
                System.IO.Stream stream = assembly.GetManifestResourceStream("SPMetalExtended.BasicTemplate.ExampleCode.SPDataExtended-html.txt");
                StreamReader sr = new StreamReader(stream);
                code = sr.ReadToEnd();
                code = code.Replace("ListName", listName).Replace("PublishingHtml", fieldName).Replace("CONTENT_FIELD", "CONTENT_FIELD" + fieldName);
                msg.AppendFormat("{0}SPMetal Extended - The code is on your Clipboard. {0}Paste the code into a class in your project and adjust the namespace.{0}", Environment.NewLine);
            }
            else if (field.TypeAsString == "Link")
            {
                Assembly assembly = this.GetType().Assembly;
                System.IO.Stream stream = assembly.GetManifestResourceStream("SPMetalExtended.BasicTemplate.ExampleCode.SPDataExtended-LinkField.txt");
                StreamReader sr = new StreamReader(stream);
                code = sr.ReadToEnd();
                code = code.Replace("ListName", listName).Replace("LinkFieldValue", fieldName).Replace("CONTENT_FIELD", "CONTENT_FIELD" + fieldName);
                msg.AppendFormat("{0}SPMetal Extended - The code is on your Clipboard. {0}Paste the code into a class in your project and adjust the namespace.{0}", Environment.NewLine);
            }
            else if (field.TypeAsString == "Attachments")
            {
                Assembly assembly = this.GetType().Assembly;
                System.IO.Stream stream = assembly.GetManifestResourceStream("SPMetalExtended.BasicTemplate.ExampleCode.SPDataExtended-attachments.txt");
                StreamReader sr = new StreamReader(stream);
                code = sr.ReadToEnd();
                code = code.Replace("ListName", listName);
                msg.AppendFormat("{0}SPMetal Extended - The code is on your Clipboard. {0}Paste the code into a class in your project and adjust the namespace.{0}", Environment.NewLine);
            }
            else if (field.TypeAsString == "Taxonomy")
            {
              //  code = BuildCode.Taxonomy(node.Text, listName, strNamespace);
            }
            else if (field.TypeAsString == "Counter")
            {
                if (field.InternalName == "ID")
                {
                    msg.Append("The ID field should be extended using the parameters.xml file.");
                }
                else
                {
                    //code = node.Text;
                }
            }
            else if (field.TypeAsString == "User")
            {
                if ((field.InternalName == "Author") || (field.InternalName == "Editor"))
                {
                    Assembly assembly = this.GetType().Assembly;
                    System.IO.Stream stream = assembly.GetManifestResourceStream("SPMetalExtended.BasicTemplate.ExampleCode.SPDataExtended-user.txt");
                    StreamReader sr = new StreamReader(stream);
                    code = sr.ReadToEnd();
                    code = code.Replace("ListName", listName);
                    if (field.InternalName == "Editor")
                    {
                        code = code.Replace("Author", "Editor").Replace("CreatedBy", "ModifiedBy");
                    }
                    msg.AppendFormat("{0}SPMetal Extended - The code is on your Clipboard. {0}Paste the code into a class in your project and adjust the namespace.{0}", Environment.NewLine);
                }
                else
                {
                    msg.AppendFormat("The field '{0}' is either: 1) part of SPMetal generation, 2) Is a hidden field and therefore should be shown using the parameters.xml file or 3) not recognised (it could be a custom field type).", node.Text);
                }
            }
            else if (field.TypeAsString == "DateTime")
            {
                if ((field.InternalName == "Created") || (field.InternalName == "Modified"))
                {
                    Assembly assembly = this.GetType().Assembly;
                    System.IO.Stream stream = assembly.GetManifestResourceStream("SPMetalExtended.BasicTemplate.ExampleCode.SPDataExtended-datetime.txt");
                    StreamReader sr = new StreamReader(stream);
                    code = sr.ReadToEnd();
                    code = code.Replace("ListName", listName);
                    if (field.InternalName == "Modified")
                    {
                        code = code.Replace("Created", "Modified");
                    }
                    msg.AppendFormat("{0}SPMetal Extended - The code is on your Clipboard. {0}Paste the code into a class in your project and adjust the namespace.{0}", Environment.NewLine);
                }
                else
                {
                    msg.AppendFormat("The field '{0}' is either: 1) part of SPMetal generation, 2) Is a hidden field and therefore should be shown using the parameters.xml file or 3) not recognised (it could be a custom field type).", node.Text);
                }
            }
            else
            {
                code = string.Format("The field '{0}' is either: 1) part of SPMetal generation, 2) Is a hidden field and therefore should be shown using the parameters.xml file or 3) not recognised (it could be a custom field type).", node.Text);
            }
            if (msg.Length > 10)
            {
                MessageBox.Show(string.Format("{0}", msg.ToString()), "SPMetal Extended code for field: " + node.Text);
                Clipboard.SetData(DataFormats.Text, code);
            }
        }
    }


}